<template>
    <div ref="pageRef" class="cashier-page">
        <div class="cashier-header">
            <div class="cashier-header-actions">
                <div @click="state.cartData.wxUserModalVisible = true">
                    <div class="iconfont icon-huiyuanqia" style="text-align: center;font-size:24px;"></div>
                    会员管理
                </div>
                <div @click="state.cartData.goodsPageModalVisible = true">
                    <div class="iconfont icon-shangpinguanli" style="text-align: center;font-size:24px;"></div>
                    商品管理
                </div>
                <div @click="state.cartData.packageModalVisible = true">
                    <div class="iconfont icon-restaurant" style="text-align: center;font-size:24px;"></div>
                    套餐</div>
            </div>
            <div class="cashier-header-data">
                <div style="display: flex;font-size: 12px;gap:10px">
                    <div>{{ cashierMode === cashierModeEnum.SETTLE ? "收银模式" : "核销模式" }}</div>
                    <div>当前门店:{{ commonStore.user.storeCode }}</div>
                </div>
                <div style="display: flex;font-size: 12px;gap:10px">
                    <div>今日开单：{{ salsOrderCount }}单</div>
                    <div>今日核销：{{ state.recordCount }}单</div>
                </div>
            </div>
        </div>
        <div class="cashier-input-container">
            <a-input style="width: 400px;" :autofocus="true"
                :placeholder="cashierMode === cashierModeEnum.SETTLE ? '请输入商品编码，商品名称，套餐编码，套餐名称' : '请输入手机号查询订单'"
                v-model:value.trim="state.cartData.formData.inputValue" @focus="handleInputValueFocus"
                @keyup.enter="handleInputValue"></a-input>
            <a-button type="primary" @click="handleInputValue">
                查询
            </a-button>
        </div>
        <div class="cashier-body">
            <a-table bordered :columns="columns"  :dataSource="state.cartData.dataSource" :rowClassName="(record, index) => {
                return state.cartData.active === index ? 'active-row' : '';
            }" :scroll="{ y: 'max-content' }" :pagination="false">
               
                <template #bodyCell="{ record, column, index }">
                    <template v-if="column.dataIndex === 'goodsCode'">
                        {{ record.goodsCode || record.id }}
                    </template>
                    <template v-if="column.dataIndex === 'goodsName'">
                        {{ record.goodsName || record.title }}
                    </template>
                    <template v-if="column.dataIndex === 'type'">
                        {{ record.goodsCode ? "商品" : "套餐" }}
                    </template>
                    <template v-if="column.dataIndex === 'packageId'">
                        {{ record.packageId || '-' }}
                    </template>
                    <template v-if="column.dataIndex === 'count'">
                        <a-input-number class="count-input" v-if="cashierMode === cashierModeEnum.SETTLE"
                            v-model:value="record.count" @focus="(e: any) => handleCountFocus(e, index)" :step="1" :min="0"
                            :keyboard="false" :max="10000" />
                        <span v-else>{{ record.count }}</span>
                    </template>
                    <template v-if="column.dataIndex === 'usedCount'">
                        {{ record.count - record.usedCount }}
                    </template>
                    <template v-if="column.dataIndex === 'useCount'">
                        <a-input-number class="count-input" v-model:value="record.useCount" :step="1" :min="0"
                            :keyboard="false" :max="record.count - record.usedCount" />
                    </template>
                    <template v-if="column.dataIndex === 'staffCode'">
                        <a-select style="width: 100px;" v-model:value="record.staffCode">
                            <a-select-option v-for="(item, index) in state.staffList" :key="index" :value="item.userId">{{
                                item.nickName }}</a-select-option>
                        </a-select>
                    </template>

                </template>
            </a-table>
        </div>
        <div class="cashier-footer">
            <div class="cashier-footer-top">
                <div class="cashier-staff">
                    <div>会员：
                        <span v-if="state.cartData.memberData.realName">
                            {{ `${state.cartData.memberData.realName}[${state.cartData.memberData.mobile}]` }}
                        </span>
                        <span v-else>-</span>
                    </div>
                    <div>收银员：{{ commonStore.user.nickName || '-' }}</div>
                </div>
                <div class="cashier-amount">
                    <div class="cashier-total" v-if="cashierMode === cashierModeEnum.SETTLE">
                        结算金额：<span class="cashier-total-value">{{ settleTotal }}</span>元
                    </div>
                    <div class="cashier-total" v-if="cashierMode === cashierModeEnum.VERIFICATION">共核销项目：
                        <span class="cashier-total-value">{{ settleUseCount }}</span>次
                    </div>
                </div>
            </div>
            <div class="cashier-footer-bottom">
                <div>
                    挂单[F1]
                </div>
                <div>
                    取单[F2]
                </div>
                <div>
                    删单[F6]
                </div>
                <div>
                    切换[F7]
                </div>
                <div>结算[F8]</div>
            </div>
        </div>
    </div>
    <GoodsSelectModal :inputValue="state.cartData.formData.inputValue" @ok="goodsSelectOk" @cancel="goodsSelectCancel"
        v-if="state.cartData.goodsModalVisible"></GoodsSelectModal>
    <EnterMember v-if="state.cartData.enterMemberVisible" @ok="memberOk" @cancel="memberCancel"></EnterMember>
    <Settlement :total="settleTotal" :staffList="state.staffList" v-if="state.cartData.settlementVisible" @ok="settleOk"
        @cancel="settleCancel"></Settlement>
    <ModeSwitch v-if="state.cartData.modeSwitchVisible" @ok="modeSwitchOk" @cancel="() => {
        state.cartData.modeSwitchVisible = false;
    }"></ModeSwitch>
    <WxUserModal v-if="state.cartData.wxUserModalVisible" @cancel="state.cartData.wxUserModalVisible = false"></WxUserModal>
    <GoodsPageModal v-if="state.cartData.goodsPageModalVisible" @cancel="state.cartData.goodsPageModalVisible = false">
    </GoodsPageModal>
    <PackageModal v-if="state.cartData.packageModalVisible" @cancel="state.cartData.packageModalVisible = false">
    </PackageModal>
    <ComfirmModal title="删单" context="此操作将清空界面数据" v-if="state.cartData.confirmModalVisible"
        @cancel="state.cartData.confirmModalVisible = false" @ok="comfirmModalOk"></ComfirmModal>
    <ComfirmModal title="挂单" context="此操作将订单暂时挂起" v-if="state.cartData.pendingVisible"
        @cancel="state.cartData.pendingVisible = false" @ok="pendingModalOk"></ComfirmModal>
    <TakeOrder v-if="state.cartData.takeOrderVisible" @ok="takeOrderOk" @cancel="takeOrderCancel"></TakeOrder>    
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, computed, watch, nextTick, onBeforeUnmount, h } from "vue";
import GoodsSelectModal from "./components/goodsSelectModal/index.vue"
import EnterMember from "./components/enterMember/index.vue";
import Settlement from "./components/settlement/index.vue";
import ModeSwitch from "./components/modeSwitch/index.vue";
import WxUserModal from "./components/wxUserModal/index.vue";
import GoodsPageModal from "./components/goodsModal/index.vue";
import PackageModal from "./components/packageModal/index.vue";
import ComfirmModal from "./components/comfirmModal/index.vue"
import TakeOrder from "./components/takeOrder/index.vue"
import { Modal, message } from "ant-design-vue";
import { CommonStore } from "@/store"
import _ from "lodash";
import { posIntRegex } from "@/utils/regex";
import { OrderService, UserService } from "@/service";
import { useRouter } from "vue-router"
import { cashierModeEnum } from "@/type";
import dayjs from "dayjs";


const commonStore = CommonStore();
const pageRef = ref();
const router = useRouter()
const initStateValues = {
    formData: {
        inputValue: "",
        staffCode: "",
        managerCode: "",
        code: "",
        form: []
    },
    memberData: {
        mobile: "",
        realName: "",
    },
    goodsModalVisible: false,
    dataSource: [],
    active: -1,
    enterMemberVisible: false,
    settlementVisible: false,
    modeSwitchVisible: false,
    wxUserModalVisible: false,
    goodsPageModalVisible: false,
    packageModalVisible: false,
    confirmModalVisible: false,
    pendingVisible: false,
    takeOrderVisible:false,
    cashierMode: cashierModeEnum.SETTLE,

}

let state = reactive<{
    cartData: {
        formData: {
            inputValue: string,
            staffCode: string;
            managerCode: string;
            code: string,
            form: any[]
        },
        memberData: {
            mobile: string;
            realName: string;
        };
        goodsModalVisible: boolean,
        dataSource: any[],
        active: number,
        enterMemberVisible: boolean;
        settlementVisible: boolean;
        modeSwitchVisible: boolean;
        wxUserModalVisible: boolean;
        goodsPageModalVisible: boolean;
        packageModalVisible: boolean;
        confirmModalVisible: boolean;
        pendingVisible: boolean;
        takeOrderVisible: boolean;
        cashierMode: cashierModeEnum;
    },
    staffList: any[],
    saleOrderList: any[],
    recordCount: number
}>({
    cartData: _.cloneDeep(initStateValues),
    staffList: [],
    saleOrderList: [],
    recordCount: 0
})


const settleTotal = computed(() => {
    return state.cartData.dataSource.reduce((last, current) => {
        return last + (current.count || 0) * current.salePrice
    }, 0);
})

const settleUseCount = computed(() => {
    return state.cartData.dataSource.reduce((last, current) => {
        return last + (current.useCount || 0)
    }, 0);
})


const modalVisible = computed(() => {
    return state.cartData.enterMemberVisible ||
        state.cartData.goodsModalVisible ||
        state.cartData.settlementVisible ||
        state.cartData.modeSwitchVisible ||
        state.cartData.wxUserModalVisible ||
        state.cartData.goodsPageModalVisible ||
        state.cartData.packageModalVisible ||
        state.cartData.confirmModalVisible ||
        state.cartData.pendingVisible ||
        state.cartData.takeOrderVisible;
})



const cashierMode = computed(() => {
    return state.cartData.cashierMode;
})



const columns = computed(() => {
    let columnList = [
        { title: "订单编码", dataIndex: "outTradeNo", },
        { title: "商品编码", dataIndex: "goodsCode", width: 100 },
        { title: "商品名称", dataIndex: "goodsName" },
        { title: "类型", dataIndex: "type", width: 100 },
        { title: "套餐编码", dataIndex: "packageId" },
        { title: "销售价格(元)", dataIndex: "salePrice" },
        { title: "购买数量", dataIndex: "count" },

    ]
    if (cashierMode.value === cashierModeEnum.VERIFICATION) {
        columnList.push({ title: "剩余次数", dataIndex: "usedCount" });
        columnList.push({ title: "核销次数", dataIndex: "useCount" });
        columnList.push({ title: "服务人", dataIndex: "staffCode" })
    }
    return columnList;
})

watch([() => state.cartData.dataSource?.length, () => state.cartData.active], () => {
    nextTick(() => {
        if (state.cartData.active === -1) {
            (pageRef.value.querySelector(".cashier-input-container input") as HTMLInputElement).focus();
            return
        }
        (Array.prototype.slice.call(pageRef.value.querySelectorAll(".count-input input"))[state.cartData.active] as HTMLInputElement).focus()
    })
})


const salsOrderCount = computed(() => {
    return state.saleOrderList.length;
})



onMounted(() => {
    const pos = (pageRef.value as HTMLDivElement).getBoundingClientRect();
    let top = pos.top;
    pageRef.value.style.height = (document.documentElement.clientHeight - top) + 'px';
    getUserList();
    getStoreOrder();
    storeTodyOrderRecordCount();
    window.addEventListener("keydown", handleKeydown)

})

onBeforeUnmount(() => {
    window.removeEventListener("keydown", handleKeydown)
})

const getStoreOrder = async () => {
    let res = await OrderService.getStoreOrder({
        storeCode: commonStore.user.storeCode!,
        startTime: dayjs().format("YYYY-MM-DD 00:00:00"),
        endTime: dayjs().format("YYYY-MM-DD 23:59:59")
    })
    if (res.code === 0) {
        state.saleOrderList = res.data;
    }
}

const storeTodyOrderRecordCount = async () => {
    let res = await OrderService.storeTodyOrderRecordCount({
        storeCode: commonStore.user.storeCode!,
        startTime: dayjs().format("YYYY-MM-DD 00:00:00"),
        endTime: dayjs().format("YYYY-MM-DD 23:59:59")
    })
    if (res.code === 0) {
        state.recordCount = res.data;
    }
}

const resetStateValues = () => {
    state.cartData = _.cloneDeep(initStateValues);
    (pageRef.value.querySelector(".cashier-input-container input") as HTMLInputElement).focus();
    getStoreOrder();
    storeTodyOrderRecordCount();
}

const getUserList = async () => {
    console.log(commonStore.user)
    if (!commonStore.user.storeCode) return message.error("用户没有绑定门店~");
    let res = await UserService.pageUser({ storeCode: commonStore.user.storeCode, pageNum: 1, pageSize: 999 });
    state.staffList = res.data?.list || [];
}

const handleKeydown = async (e: any) => {

    if (modalVisible.value) return;
    const code = e.code;
    if (["ArrowDown", "ArrowUp", "Enter", "Esc", "NumpadEnter", "F8", "F7", "F1","F5"].includes(code)) {
        e.preventDefault();
    }
    if (code === "ArrowDown") {
        state.cartData.active++;
        if (state.cartData.active > state.cartData.dataSource.length - 1) state.cartData.active = -1;
    } else if (code === "ArrowUp") {
        state.cartData.active--;
        if (state.cartData.active < -1) state.cartData.active = state.cartData.dataSource.length - 1;
    } else if (code === "Enter" || code === "NumpadEnter") {
        if (state.cartData.active == -1) return;
        state.cartData.active++;
        if (state.cartData.active > state.cartData.dataSource.length - 1) state.cartData.active = -1;
    } else if (code === "F8") {
        if (cashierMode.value === cashierModeEnum.SETTLE) {
            settleActions();
        } else {
            useOrderCount()
        }
    } else if (code === "F7") {
        state.cartData.modeSwitchVisible = true;
    } else if (code === "Delete") {
        state.cartData.dataSource.splice(state.cartData.active, 1)
    } else if (code === "F6") {
        state.cartData.confirmModalVisible = true;
    } else if (code === "F1") {
        if (cashierMode.value !== cashierModeEnum.SETTLE) return message.error("请切换到收银模式")
        if (!state.cartData.dataSource.length) return message.error("请先添加商品到购物车")
        state.cartData.pendingVisible = true;
    }else if(code === "F2"){
        if (cashierMode.value !== cashierModeEnum.SETTLE) return message.error("请切换到收银模式")
        if (state.cartData.dataSource.length) return message.error("购物车有正在结算的订单")
        state.cartData.takeOrderVisible = true;
    }

}

const settleActions = async () => {
    //选择会员
    if (!state.cartData.memberData.mobile) {
        state.cartData.enterMemberVisible = true;
        return;
    }
    //结算授权
    if (!state.cartData.formData.staffCode || !state.cartData.formData.code) {
        state.cartData.settlementVisible = true;
        return;
    }
    if (state.cartData.dataSource.length == 0) {
        return message.error("请选择商品")
    } else {
        const formData: any = _.cloneDeep(state.cartData.formData);
        formData.mobile = state.cartData.memberData.mobile;
        formData.customerName = state.cartData.memberData.realName
        formData.storeCode = commonStore.user.storeCode;
        formData.payType = 2;
        let errors: string[] = [];
        formData.form = state.cartData.dataSource.map((goods) => {
            if (!goods.count || !posIntRegex.test(goods.count)) {
                errors.push(`商品数量输入有误~`)
            }
            return {
                goodsCode: goods.goodsCode,
                goodsName: goods.goodsName,
                packageId: goods.packageId || "",
                packageName: goods.packageName || "",
                type: goods.packageId ? 2 : 1,
                count: goods.count,
                salePrice: goods.salePrice,
                payPrice: goods.salePrice,
                outTradeNo: "",
                mainImage: goods.mainImage,
                mobile: state.cartData.memberData.mobile,
                groupNum: goods.groupNum
            }
        })
        if (errors.length) return message.error(errors[0])
        console.log("----->", formData)
        let resVo = await OrderService.createOrder(formData);
        console.log("resVo--->", resVo)
        if (resVo.code === 0) {
            message.success("支付成功");
            resetStateValues();
        }else{
            state.cartData.formData.code = "";
        }
    }
}

const useOrderCount = async () => {
    const formData: any = _.cloneDeep(state.cartData.formData);
    let errors: string[] = [];
    formData.form = state.cartData.dataSource.map((goods) => {
        if ((goods.useCount && !goods.staffCode) || (!goods.useCount && goods.staffCode)) {
            return errors.push("核销次数和门店服务人员不能只填写其中一个");
        }
        return goods;
    }).filter((goods) => goods.useCount)

    if (errors.length) return message.error(errors[0])
    if (!formData.form.length) return message.error("没有核销项目")
    let resVo = await OrderService.useOrderCount(formData);
    if (resVo.code === 0) {
        Modal.info({
            title: "核销成功",
            content: h('div', {}, [
                h('span', {}, `核销次数`)
            ]),
            onOk: () => {
                resetStateValues();
            }
        })
    }


}

const handleInputValueFocus = () => {
    state.cartData.active = -1;
}

const handleCountFocus = (e: any, index: number) => {
    console.log(index)
    state.cartData.active = index;
}

const handleInputValue = async () => {
    if (modalVisible.value) return;
    if (cashierMode.value === cashierModeEnum.SETTLE) {
        if (!state.cartData.formData.inputValue?.length) return message.error("请输入商品信息");
        state.cartData.goodsModalVisible = true;
        (pageRef.value.querySelector(".cashier-input-container input") as HTMLInputElement).blur();
    } else if (cashierMode.value === cashierModeEnum.VERIFICATION) {
        if (!state.cartData.formData.inputValue?.length) return message.error("请输入会员手机号");
        let resVo = await OrderService.unusedOrder({ mobile: state.cartData.formData.inputValue });
        if (resVo.code === 0) {
            console.log("resVo--->", resVo.data)
            state.cartData.dataSource = resVo.data;
        }
    }

}

const goodsSelectOk = (goods: any) => {
    if (!state.cartData.dataSource.length) {
        goods.groupNum = 0;
    }
    goods.groupNum = (Math.max(...state.cartData.dataSource.map(goods => goods.groupNum) || 0)) + 1;
    state.cartData.formData.inputValue = "";
    let activeIndex = state.cartData.dataSource.findIndex((goodsItem) => {
        console
        if (goodsItem.goodsCode && goodsItem.goodsCode === goods.goodsCode) return true;
        if (goodsItem.packageId && goodsItem.packageId === goods.packageId) return true;
    })
    console.log(activeIndex)
    if (activeIndex > -1) {
        state.cartData.active = activeIndex;
        state.cartData.dataSource[activeIndex].count++;
    } else {
        state.cartData.active = state.cartData.dataSource.length;
        goods.count = 1;
        state.cartData.dataSource.push(goods);
    }

    state.cartData.goodsModalVisible = false;
}

const goodsSelectCancel = () => {
    state.cartData.goodsModalVisible = false;
}

const memberOk = (val: any) => {
    state.cartData.memberData.mobile = val.mobile;
    state.cartData.memberData.realName = val.realName;
    state.cartData.enterMemberVisible = false;
    settleActions();
}
const memberCancel = () => {
    state.cartData.enterMemberVisible = false;
}

const settleOk = (val: any) => {
    state.cartData.formData.staffCode = val.staffCode;
    state.cartData.formData.managerCode = val.managerCode;
    state.cartData.formData.code = val.code;
    state.cartData.settlementVisible = false
    settleActions();
}

const settleCancel = () => {
    state.cartData.settlementVisible = false
}

const modeSwitchOk = (val: any) => {
    state.cartData.modeSwitchVisible = false;

    if (state.cartData.cashierMode != val) {
        resetStateValues();
        state.cartData.cashierMode = val;
        console.log(state.cartData.cashierMode, val)

    }
}

const comfirmModalOk = () => {
    state.cartData.confirmModalVisible = false;
    resetStateValues();
}

const pendingModalOk = () => {
    state.cartData.pendingVisible = false;
    commonStore.$state.cartDataList.push({...state.cartData,createTime:dayjs().format("YYYY-MM-DD HH:mm:ss")});
    resetStateValues();
}

const takeOrderOk = (order:any) =>{
    
    state.cartData.takeOrderVisible = false;
    state.cartData = {...order};
    console.log("order--->",state.cartData)
} 

const takeOrderCancel=()=>{
    state.cartData.takeOrderVisible = false;
}

</script>
<style lang="less" scoped>
.cashier-page {
    background-color: white;
    height: 100%;
    display: flex;
    flex-direction: column;
}

.cashier-header {
    display: flex;
    background-color: lighten(#7546c9, 10);
    color: white;
    padding: 10px;
    justify-content: space-between;
    align-items: center;
}

.cashier-header-actions {
    display: flex;
    gap: 20px;
    cursor: pointer;
}

.cashier-header-data {}

.cashier-input-container {
    display: flex;
    padding: 10px;
    gap: 8px;
}

.cashier-body {
    background-color: white;
    flex: 1;

    :deep(.ant-table-row.active-row) {
        .ant-table-cell {
            border-top: 2px solid #7546c9;
            border-bottom: 2px solid #7546c9;
            background-color: lighten(#7546c9, 40)
        }
    }
}

.cashier-footer {
    background-color: #7546c9;
    width: 100%;
    height: 140px;
}

.cashier-footer-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
}


.cashier-staff {
    padding: 20px;
    color: #fff;
    font-size: 13px;
    line-height: 32px;
    float: left;
}

.cashier-amount {
    float: right;
    padding: 20px;
    color: #fff;
    font-size: 13px;
    display: flex;
    justify-content: baseline;

}

.cashier-total-value {
    font-size: 40px;
    font-weight: bolder;
}

.cashier-footer-bottom {
    height: 100px;
    display: flex;
    gap: 100px;
    color: silver;
    justify-content: center;
}</style>